import axios from "axios";
import dayjs from "dayjs";
// import * as XLSX from "xlsx";
// import ExcelJS from "exceljs";
import * as ExcelJS from "exceljs/dist/exceljs.min.js";
// import * as FileSaver from "file-saver";
import FileSaver from "file-saver";
import { ElNotification, ElMessage, ElMessageBox } from "element-plus";

const LOG_INFO = true;
const USER_CONTENT = [];
const USER_DETAILS = [];
const WORK_PAYMENTS = {
  commuting: 80,
  overnight: 30,
};

export default function (workData, workRaw, workDeclarations, workRange) {
  return new Promise((resolve, reject) => {
    loadParams()
      .then(() => {
        let fileName = "值班数据统计@" + dayjs().format("YYYYMMDD_HHmmss");
        const workbook = new ExcelJS.Workbook();
        // 明细表
        const defaultSheet = workbook.addWorksheet("值班统计明细", {
          views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
        });
        generateDefaultSheet(workData, defaultSheet);
        // 远郊报表
        const commutingSheet = workbook.addWorksheet("远郊申报表", {
          views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
        });
        generateCommutingSheet(workData, commutingSheet);
        // 夜餐
        const overnightSheet = workbook.addWorksheet("夜餐申报表", {
          views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
        });
        generateOvernightSheet(workData, overnightSheet, workRange);
        // 加班
        const overtimeSheet = workbook.addWorksheet("加班申报表", {
          views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
        });
        generateOvertimeSheet(workData, overtimeSheet);
        // 申报
        const declarationSheet = workbook.addWorksheet("人工申报记录", {
          views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
        });
        generateDeclarationSheet(workDeclarations, declarationSheet);
        // 导出
        LOG_INFO ? console.log("值班统计", workbook) : null;
        workbook.xlsx.writeBuffer().then((buffer) => {
          const fileData = new Blob([buffer], {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8",
          });
          FileSaver.saveAs(fileData, fileName + ".xlsx");
          resolve(fileName);
        });
      })
      .catch((err) => {
        reject(err);
      });
  });
}

function generateDefaultSheet(workData, worksheet) {
  LOG_INFO ? console.log("值班统计", "generateDefaultSheet") : null;
  worksheet.columns = [
    { header: "姓名", key: "name", width: 10 },
    { header: "工牌号", key: "uid", width: 12 },
    { header: "小时数", key: "hours", width: 10 },
    { header: "远郊次数", key: "commutingDays", width: 10 },
    { header: "远郊明细", key: "commutingDates", width: 22 },
    { header: "夜餐次数", key: "overnightDays", width: 10 },
    { header: "夜餐明细", key: "overnightDates", width: 22 },
    { header: "加班天数", key: "overtimeDays", width: 10 },
    { header: "加班明细", key: "overtimeDates", width: 30 },
    { header: "工作天数", key: "workingDays", width: 10 },
    { header: "工作明细", key: "workingDates", width: 30 },
  ];
  for (let i = 0; i < workData.length; i++) {
    let cell = workData[i];
    worksheet.addRow({
      name: cell.name,
      uid: cell.uid,
      hours: cell.hours.toFixed(1),
      commutingDays: cell.commutingDays,
      commutingDates:
        cell.commutingDays > 0 && cell.commutingDates
          ? cell.commutingDates
              .map((cd) => `${cd.date} 计${cd.days}天`)
              .join("\r\n")
          : "无",
      overnightDays: cell.overnightDays,
      overnightDates:
        cell.overnightDays > 0 && cell.overnightDates
          ? cell.overnightDates
              .map((od) => `${od.date} 计${od.days}天`)
              .join("\r\n")
          : "无",
      overtimeDays: cell.overtimeDays,
      overtimeDates:
        cell.overtimeDays > 0 && cell.overtimeDays
          ? cell.overtimeDates
              .map(
                (od) =>
                  `${od.date} ${od.duration.toFixed(1)}小时 计${od.days}天`
              )
              .join("\r\n")
          : "无",
      workingDays: cell.workingDays,
      workingDates:
        cell.workingDays > 0 && cell.workingDates
          ? cell.workingDates
              .map(
                (wd) =>
                  `${wd.date} ${wd.duration.toFixed(1)}小时 计${wd.days}天`
              )
              .join("\r\n")
          : "无",
    });
  }

  setDefaultSheetStyle(worksheet);
  LOG_INFO ? console.log("值班统计", "generateDefaultSheetFinished") : null;
}

function generateCommutingSheet(workData, worksheet) {
  LOG_INFO ? console.log("值班统计", "generateCommutingSheet") : null;
  worksheet.columns = [
    { header: "OA名", key: "name", width: 10 },
    { header: "姓名", key: "nameReal", width: 10 },
    { header: "工牌号", key: "uid", width: 12 },
    { header: "身份证号码", key: "pid", width: 24 },
    { header: "部门(科室)", key: "org", width: 12 },
    { header: "远郊次数", key: "commutingDays", width: 10 },
    { header: "远郊金额", key: "commutingPays", width: 10 },
  ];
  for (let i = 0; i < workData.length; i++) {
    let cell = workData[i];
    let details = findUserDetailByUid(cell.uid);
    worksheet.addRow({
      name: cell.name,
      nameReal: cell.name.replace(/\d+/g, ""),
      uid: cell.uid,
      pid: details.pid,
      org: details.org,
      commutingDays: cell.commutingDays,
      commutingPays: cell.commutingDays * WORK_PAYMENTS.commuting,
    });
  }
  setDefaultSheetStyle(worksheet);
  LOG_INFO ? console.log("值班统计", "generateCommutingSheetFinished") : null;
}

function generateOvernightSheet(workData, worksheet, workRange) {
  LOG_INFO ? console.log("值班统计", "generateOvernightSheet") : null;
  let columns = [
    { header: "OA名", key: "name", width: 10 },
    { header: "姓名", key: "nameReal", width: 10 },
    { header: "工牌号", key: "uid", width: 12 },
    { header: "身份证号码", key: "pid", width: 24 },
    { header: "部门(科室)", key: "org", width: 12 },
    { header: "总金额", key: "overnightPays", width: 10 },
  ];
  let startDate = dayjs(workRange[0]);
  let endDate = dayjs(workRange[1]);
  let dateLength = endDate.diff(startDate, "day");
  let dateColumns = [];
  for (let i = 0; i <= dateLength; i++) {
    let currentDate = startDate.add(i, "day");
    let label = currentDate.format("DD") + "日";
    let key = "_" + currentDate.format("YYYYMMDD");
    columns.push({ header: label, key, width: 6 });
    dateColumns.push({ key, date: currentDate.format("YYYY-MM-DD") });
  }
  worksheet.columns = columns;
  for (let i = 0; i < workData.length; i++) {
    let cell = workData[i];
    let details = findUserDetailByUid(cell.uid);
    let row = {
      name: cell.name,
      nameReal: cell.name.replace(/\d+/g, ""),
      uid: cell.uid,
      pid: details.pid,
      org: details.org,
      overnightPays: cell.overnightDays * WORK_PAYMENTS.overnight,
    };
    for (let j = 0; j < dateColumns.length; j++) {
      let key = dateColumns[j].key;
      let dateStr = dateColumns[j].date;
      let filterResult = cell.overnightDates.filter(
        (ods) => ods.date == dateStr
      );
      if (filterResult.length > 0) {
        row[key] = filterResult[0].days * WORK_PAYMENTS.overnight;
      } else {
        row[key] = 0;
      }
    }
    worksheet.addRow(row);
  }
  setDefaultSheetStyle(worksheet);
  LOG_INFO ? console.log("值班统计", "generateOvernightSheetFinished") : null;
}

function generateOvertimeSheet(workData, worksheet) {
  LOG_INFO ? console.log("值班统计", "generateCommutingSheet") : null;
  worksheet.columns = [
    { header: "OA名", key: "name", width: 10 },
    { header: "姓名", key: "nameReal", width: 10 },
    { header: "工牌号", key: "uid", width: 12 },
    { header: "身份证号码", key: "pid", width: 24 },
    { header: "部门(科室)", key: "org", width: 12 },
    { header: "加班时段", key: "overtimeDetails", width: 60 },
    { header: "加班小时数", key: "overtimeHours", width: 15 },
  ];
  for (let i = 0; i < workData.length; i++) {
    if (workData[i].overtimeDays > 0) {
      let cell = workData[i];
      let details = findUserDetailByUid(cell.uid);
      worksheet.addRow({
        name: cell.name,
        nameReal: cell.name.replace(/\d+/g, ""),
        uid: cell.uid,
        pid: details.pid,
        org: details.org,
        overtimeDetails: cell.overtimeDates
          .map((ods) => {
            return `${ods.from} 至 ${ods.to}`;
          })
          .join(";\n"),
        overtimeHours: cell.overtimeDays * 8,
      });
    }
  }
  setDefaultSheetStyle(worksheet);
  LOG_INFO ? console.log("值班统计", "generateCommutingSheetFinished") : null;
}

function findUserDetailByUid(uid) {
  let details = USER_DETAILS.filter((cell) => cell.uid == uid);
  if (details.length > 0) {
    return details[0];
  } else {
    return {
      uid: -1,
      name: "?",
      pid: "?",
    };
  }
}

function findUserOrgByUid(uid) {
  let result = USER_CONTENT.filter((cell) => cell.code == uid);
  if (result.length > 0) {
    return result[0].orgName;
  } else {
    return "?";
  }
}

function loadParams() {
  return new Promise((resolve, reject) => {
    axios
      .post("api/common_params.php", {
        method: "GET",
        keys: ["WORK_PAYMENTS", "WORK_USER_DETAILS", "ATCOS_USERS_CONTENT"],
      })
      .then((response) => {
        WORK_PAYMENTS.commuting = response.data["WORK_PAYMENTS"].commuting;
        WORK_PAYMENTS.overnight = response.data["WORK_PAYMENTS"].overnight;
        USER_DETAILS.length = 0;
        USER_DETAILS.push(...response.data["WORK_USER_DETAILS"]);
        USER_CONTENT.length = 0;
        USER_CONTENT.push(...response.data["ATCOS_USERS_CONTENT"]);
        resolve(response.data);
      })
      .catch((error) => {
        ElNotification({ type: "error", message: "读取证件信息出错" });
        reject(error);
      });
  });
}

function setDefaultSheetStyle(worksheet) {
  worksheet.properties.defaultRowHeight = 15;
  worksheet.eachRow(function (row, rowNumber) {
    row.eachCell(function (cell, colNumber) {
      cell.alignment = {
        vertical: "middle",
        horizontal: "center",
        wrapText: true,
      };
      if (rowNumber == 1) {
        cell.font = { size: 12, bold: true };
      } else {
        cell.font = { size: 12 };
      }
    });
  });
}

function generateDeclarationSheet(workDeclarations, worksheet) {
  LOG_INFO ? console.log("申报明细", "generateDeclarationSheet") : null;
  worksheet.columns = [
    { header: "姓名", key: "userName", width: 12 },
    { header: "工牌号", key: "userId", width: 12 },
    { header: "开始时间", key: "startTime", width: 30 },
    { header: "结束时间", key: "endTime", width: 30 },
    { header: "申报时间", key: "version", width: 30 },
    { header: "证明人", key: "witnessName", width: 12 },
    { header: "备注", key: "remark", width: 50 },
  ];
  for (let i = 0; i < workDeclarations.length; i++) {
    let cell = workDeclarations[i];
    worksheet.addRow({
      userName: cell.userName,
      userId: cell.userId,
      startTime: cell.startTime,
      endTime: cell.endTime,
      version: cell.version,
      witnessName: cell.witnessName,
      remark: cell.remark,
    });
  }
  setDefaultSheetStyle(worksheet);
  LOG_INFO ? console.log("值班统计", "generateDeclarationSheet") : null;
}
